/***************************************************************************
 * Open Object Oriented ANSI C                                             *
 ***************************************************************************
 * Code given under the terms of GNU General Public Licence (GPLv3)        *
 * and without any waranties of any kind including but not limitative to   *
 * waranties on merchandability or any particular applications fitness.    *
 * For more information on GNU/GPL go on :                                 *
 * "http://www.gnu.org/copyleft/gpl.html"                                  *
 *                                                                         *
 * You are allowed to use it for any purposes in the terms of GNU/GPLv3    *
 * (or more).                                                              *
 * This text MUST stay in state on copyed sources (or sources using it)    *
 * and must not be altered.                                                *
 * You are allowed to add your name at the end of the Copylefs list.       *
 ***************************************************************************
 * Copylefts List :                                                        *
 ***************************************************************************
 * 2010-03-20 Patrick PIGNOL <pignol_patrick@hotmail.com> (Original)       *
 * (Type your name here if needed)                                         *
 ***************************************************************************/
#ifndef STRING_H_INCLUDED
#define STRING_H_INCLUDED

#define STRING_TYPEID 7

typedef enum StringDirection
{
    StringDirectionBackward = -1,
    StringDirectionForward = 1
}StringDirection;

typedef enum StringCompared
{
    StringComparedBefore = -1,
    StringComparedEqual = 0,
    StringComparedAfter = 1
}StringCompared;

typedef struct StringVirtualTable StringVirtualTable;
typedef struct String String;

#include "Bool.h"
#include "Class.h"

struct StringVirtualTable
{
    unsigned long int TypeID;
    ClassInterface* Interface;
    ClassVirtualTable* AncestorTable;
    unsigned long int ReferenceCount;
    String* (*new)(unsigned long int pArgsCount, va_list* pParameters);
    StringVirtualTable* (*Initialize)(String* this, unsigned long int pArgsCount, va_list* pParameters);
    void (*Garbage)(String* this);
    unsigned long int (*TypeOf)(String* this);
    bool (*IsSameTypeThanTypeID)(String* this, unsigned long int pTypeID);
    bool (*IsKindOfTypeID)(String* this, unsigned long int pTypeID);
    bool (*IsSameTypeThan)(String* this, Class* pSource);
    bool (*IsKindOf)(String* this, Class* pSource);
};

struct String
{
    StringVirtualTable* VirtualTable;
    void (*Constructor)(String* this, unsigned long int pArgsCount, va_list* pParameters); /* Constructor pointer of object. Called by Initialise(). Must be propagated on inherited that do not override.*/
    void (*Destructor)(String* this); /* Destructor pointer of object. Called by Garbage(). Must be propagated on inherited that do not override.*/
    String* (*Clone)(String* this);
    unsigned long int aLength;
    char* aString;
    unsigned long int (*Length)(String* this);
    const char* const (*CharPointer)(String* this, const char* pString);
    void (*AppendString)(String* this, const String* pString);
    void (*PrependString)(String* this, const String* pString);
    bool (*FindChar)(String* this, unsigned long int* pIndex, char pChar, StringDirection pDirection);
    bool (*FindCharNext)(String* this, unsigned long int* pIndex, char pChar, unsigned long int pStarIndex, StringDirection pDirection);
    bool (*FindString)(String* this, unsigned long int* pIndex, const String* pSubString, StringDirection pDirection);
    bool (*FindStringNext)(String* this, unsigned long int* pIndex, unsigned long int pStartIndex, const String* pSubString, StringDirection pDirection);
    bool (*IsEmptyOfChar)(String* this, char pChar);
    bool (*IsEmptyOfString)(String* this, String* pString);
    char* (*SubChar)(String* this, unsigned long int pIndex, unsigned long int pLength);
    String* (*SubString)(String* this, unsigned long pStart, unsigned long pLength);
    StringCompared (*Compare)(String* this, String* pString);
    void (*Remove)(String* this, unsigned long int pStartIndex, unsigned long int pLength);
    void (*Replace)(String* this, String* pSubString, unsigned long int pStartIndex);
    void (*Reverse)(String* this);
};

String* StringNew(unsigned long int pArgsCount, va_list* pParameters);
StringVirtualTable* StringInitialize(String* this, unsigned long int pArgsCount, va_list* pParameters); /* Called by new method to create object in heap memory. Must be propagated on inherited that do not override.*/
unsigned long int StringTypeOf(String* this);
void StringConstructor(String* this, unsigned long int pArgsCount, va_list* pParameters); /* Constructor pointer of object. Called by Initialise(). Must be propagated on inherited that do not override.*/
void StringDestructor(String* this); /* Destructor pointer of object. Called by Garbage(). Must be propagated on inherited that do not override.*/
String* StringClone(String* this);
unsigned long int StringLength(String* this);
const char* const StringCharPointer(String* this, const char* pString);
void StringAppendString(String* this, const String* pString);
void StringPrependString(String* this, const String* pString);
bool StringFindChar(String* this, unsigned long int* pIndex, char pChar, StringDirection pDirection);
bool StringFindCharNext(String* this, unsigned long int* pIndex, char pChar, unsigned long int pStarIndex, StringDirection pDirection);
bool StringFindString(String* this, unsigned long int* pIndex, const String* pSubString, StringDirection pDirection);
bool StringFindStringNext(String* this, unsigned long int* pIndex, unsigned long int pStartIndex, const String* pSubString, StringDirection pDirection);
bool StringIsEmptyOfChar(String* this, char pChar);
bool StringIsEmptyOfString(String* this, String* pString);
char StringSubChar(String* this, unsigned long int pIndex);
String* StringSubString(String* this, unsigned long pStartIndex, unsigned long pLength);
StringCompared StringCompare(String* this, String* pString);
void StringRemove(String* this, unsigned long int pStartIndex, unsigned long int pLength);
void StringReplace(String* this, String* pSubString, unsigned long int pStartIndex);
void StringReverse(String* this);

#endif /* STRING_H_INCLUDED*/
